/*
字符串替换，去除两边的空格
gcc useful_code.cpp -lstdc++ -o bin/useful_code && bin/useful_code
gcc useful_code.cpp -std=c++11 -lstdc++ -o bin/useful_code && bin/useful_code
*/
#include <algorithm>
#include <cmath>
#include <iostream>
#include <numeric>
#include <vector>

#define element_size 3

// function to calculate dot product of two vectors
int dot_product(int vector_a[], int vector_b[]) {
    int product = 0;
    for (int i = 0; i < element_size; i++) {
        product = product + vector_a[i] * vector_b[i];
    }
    return product;
}

int dot_product1(const std::vector<double> &a, const std::vector<double> &b,
                 double &out) {
    for (size_t i = 0; i < a.size(); ++i) {
        out += a.at(i) * b.at(i);
    }
    return 1;
}

// function to calculate cross product of two vectors
void cross_product(int vector_a[], int vector_b[], int temp[]) {
    temp[0] = vector_a[1] * vector_b[2] - vector_a[2] * vector_b[1];
    temp[1] = -(vector_a[0] * vector_b[2] - vector_a[2] * vector_b[0]);
    temp[2] = vector_a[0] * vector_b[1] - vector_a[1] * vector_b[0];
}

double myfunction(double num) { return exp(num); }
// template <typename T>
// void softmax(const typename ::std::vector<T> &v, typename ::std::vector<T>
// &s) {
//     double sum = 0.0;
//     transform(v.begin(), v.end(), s.begin(), myfunction);
//     sum = accumulate(s.begin(), s.end(), sum);
//     for (size_t i = 0; i < s.size(); ++i) {
//         s.at(i) /= sum;
//     }
// }
int softmax(const std::vector<double> &in, std::vector<double> &out) {
    double sum = 0.0;
    std::transform(in.begin(), in.end(), out.begin(), myfunction);
    sum = accumulate(out.begin(), out.end(), sum);
    for (size_t i = 0; i < out.size(); ++i) {
        out.at(i) /= sum;
    }
    return 1;
}

int main() {
    double a[] = {1.0, 3.0, 2.0};
    std::vector<double> v_a(a, a + sizeof a / sizeof a[0]), v_b(v_a);
    std::vector<double>::const_iterator it = v_a.begin();
    for (; it != v_a.end(); ++it) {
        // std::cout << *it << " ";
    }
    // std::cout << std::endl;
    softmax(v_a, v_b);
    it = v_b.begin();
    for (; it != v_b.end(); ++it) {
        // std::cout << *it << " ";
    }
    // std::cout << std::endl;

    int vector_a[] = {4, 2, -1};
    int vector_b[] = {5, 7, 1};
    int temp[3];
    // std::cout << "Dot product:";
    // std::cout << dot_product(vector_a, vector_b) << std::endl;
    // std::cout << "Cross product:";
    cross_product(vector_a, vector_b, temp);
    for (int i = 0; i < element_size; i++) {
        // std::cout << temp[i] << std::endl;
    }

    std::vector<double> v_a1(vector_a,
                             vector_a + sizeof vector_a / sizeof vector_a[0]);
    std::vector<double> v_b1(vector_b,
                             vector_b + sizeof vector_b / sizeof vector_b[0]);
    double out = 0.0;
    int ret = dot_product1(v_a1, v_b1, out);
    // std::cout << "out:" << out << std::endl;

    std::vector<double> weight1 = {-0.21204972814721312,-0.1908442610328168,-0.17954049681902706,-0.3148763549278369,-0.06684729282365076,-0.030071015128420142,-0.1382223185264866,-0.3942202668423816,0.013362046411413434,-0.06760716828335998,0.21979093498985777,-0.2528463422005102,-0.48910761715200624,0.023704292868864874,-0.6392241450968343,0.6008093935050735,-0.34935180776585717,-0.09942492667285241,-0.07626329298334489,-0.14976794576080754,-0.19003023726033635,-0.45305471324612034,-0.24060429101553452,-0.18656352297931664,0.1055334144214401,0.036900100485985694,-0.10490721000885964,0.21604675126603817,-0.24230538261551968,-0.4366434383206928,0.4924623115013598,-0.0231258041457021,3.2679510196032515,-0.23215856814491012,0.5819264089627516,-0.01112491132120164,0.0,0.0,0.0,0.0,0.0,0.0,0.21979093498985777,-0.2528463422005102,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-0.24230538261551968,0.0,0.0,0.0,3.2679510196032515,0.0,0.0,0.0,-0.09523307420181361,-0.07144652134552035,-0.22518694608655387,-0.09591194758138537,-0.1762531526256802,-0.015812183840582795,-0.0694080711936824,-0.6858891357170157,0.22507758971081493,0.21297801808587444,-0.0837830749852031,-0.0083951952176392,-0.17497534300065368,-0.03563223652287919,-0.05892556562900198,-0.05604448849911487,-0.0028155047482782756,0.5145371174390073,-0.03599553917713537,-0.03142807695768216,-0.06141283783564898,-0.00228808083596798,-0.03183341338335511,-0.002092439697046871,-0.016864313154507347,1.313890636944752,-0.06314500113467865,-0.10261371543505379,-0.12430816606906686,-0.03761979853124297,-0.08626106475786609};
    std::vector<double> weight2 = {0.43530069047154907,-0.13696711838133924,-0.6860966496589034,0.8725358559120033,-0.25105288520840185,-0.34112819940576733,-0.5135469599248934,-0.4300021427272764,-0.30166405949038294,-0.20359703274121377,0.2048234262840082,-0.8038559180462452,0.4909139164233733,-0.7535162987007308,-1.089254064041678,-0.39572347918915146,-0.5624107003819825,-0.620660526633834,-0.2667698158978826,-0.2766452377338246,-0.9323017860336047,-1.5260396937722538,-0.9477219765805531,-0.7118799844396052,-0.46010705392417767,0.20542423142375404,0.10569915306070969,-0.4679354144479858,-0.06237418929026168,-0.1453413908046013,6.067350155916936,-0.45224080468988875,0.11340262039712753,0.2956256873806904,-0.16041528222591311,-0.041502210254595745,0.0,0.0,0.0,0.0,0.0,0.0,0.2048234262840082,-0.8038559180462452,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-0.06237418929026168,0.0,0.0,0.0,0.11340262039712753,0.0,0.0,0.0,1.155769482489541,-0.16586432901250464,0.7273703108066633,-0.35112921987049844,1.9297929786169006,-0.2991456368574893,-0.25157904893003913,-1.0518050682720341,-0.4366725829760159,-0.13460580178998424,-0.21603028687049,-0.10231949240442414,-0.6693962170833275,-0.2779248964477592,-0.1277869151089049,-0.27608951642367585,-0.028308878391579438,-0.19781645675858395,-0.1486009118314541,-0.14586942302845812,-0.27167202702917587,-0.02688869347979591,-0.18312290693407504,-0.019682853726212906,-0.07306912901805752,0.8042457586093871,-0.21007672325450608,-0.12688444728599813,0.4533037419769119,-0.37949394056164065,-1.1905309457953206};
    std::vector<double> weight3 = {0.11238252966271448,-1.1956369494814711,-0.8943680898200983,-0.1609896977860892,-2.0352722765039077,0.1425620880872463,0.3342003294385341,-1.3283183397765983,-0.0263197744442364,-0.23135701727819208,-0.18784144621045046,-1.0002054311908677,-0.9219651368430986,0.9828692683366288,0.6071058243359377,-0.4256382178724023,-0.6900577666856139,-0.2911541753908683,0.25237365397179945,1.0163806722783506,-0.5206034924904658,1.5953887768619726,-0.19884247135665323,0.6877039325742532,1.056121156761439,0.19119335052339928,0.11384761551954169,1.333197073616636,-0.42828429443619204,-0.7728458602782049,-1.4425913728002377,-0.08461758799230476,-0.1871311265321414,-0.3530869362888218,0.44660834905795893,-0.538832334586981,0.0,0.0,0.0,0.0,0.0,0.0,-0.18784144621045046,-1.0002054311908677,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-0.42828429443619204,0.0,0.0,0.0,-0.1871311265321414,0.0,0.0,0.0,-3.187891647707466,1.2284787366985743,-1.8593440327343587,-0.5564529880661815,-1.4940599805597867,-0.47408491619848847,2.6642330935964402,-0.6813688905535297,2.3534557534777756,3.1093002986287646,-1.5329140704347761,-0.7517512647162218,-0.6787009512589369,2.2972848004151456,1.7388526065993914,-0.03187893863754431,0.7125881453287887,2.5444218460573076,1.5736849992502868,-1.4321170270778925,-2.076614987138083,-0.3883319262228253,-1.4785507910456865,0.6739072702693036,-0.8265435005755354,-0.8850524543599024,1.9761899542178911,2.6590706200555165,-0.3693944740206675,-0.8926949632737611,1.0213989710170848};
    std::vector<double> weight4 = {-0.04183887350753842,0.45410162522548003,1.4255352984341831,0.1990931159269711,2.1111960565185255,0.3186821145171776,0.5184607963644023,2.142280781528006,-0.43301787913461526,0.749843058533973,0.8391028418511108,-0.6610040713140074,1.2789989744478754,-1.9794418702622216,0.1980299573083147,0.6913660726433634,1.612479239553801,0.48142371702127895,-0.6282179551901411,-0.5018973386371968,1.6207676904854924,-0.5749919313727226,0.7379752899031332,0.05497901680237858,-0.11106796476200632,-0.3037389734527445,0.28445689547030284,-0.9273271189126981,0.7897759176582424,-1.251711768953706,-2.794202151629919,0.07542614255382821,-0.7208682992951689,0.7509069203989235,-0.485877968893003,0.6382600632786913,0.0,0.0,0.0,0.0,0.0,0.0,0.8391028418511108,-0.6610040713140074,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.7897759176582424,0.0,0.0,0.0,-0.7208682992951689,0.0,0.0,0.0,2.3834107671119305,-0.32139664956777564,1.4852501025873415,0.33049172452683695,-3.0524287350969628,-0.9313268538992765,-1.9640831795424334,1.4672672993920912,-2.140354986186093,-2.737653144224783,-1.109460075444394,1.4503832838174195,0.1373491453395653,-1.1556934136846173,-1.9510740370395696,1.2595442516821507,-0.43142368045753854,-1.8241899146189198,-1.4778728611300311,1.6386011251492956,2.704282569172963,0.5351783190247642,1.4969034398706647,-0.5233599590000593,-0.41591416093903877,1.0797251985430139,-1.6573365730503515,-0.83916641329303,-0.8888172772832019,1.0152222193048488,0.3778469549831056};
    std::vector<double> weight5 = {-0.41210149612795444,-0.19232907315285253,-1.010110951403183,-0.4631177964466882,-1.376497091635652,-0.28420417181799584,-0.8967278144208729,-1.464958724761168,1.4449564781946505,-0.18937972718931528,-1.011467425702127,1.939294365360964,-0.8884184936251713,2.272065240711947,0.042464771577813115,-0.00866913937592524,-1.6187642517345595,0.2522493387302499,1.4442030877998433,-1.0687588846110614,-1.9366615238245906,-1.8952168443907313,-0.41156431724913595,-1.0700768224352997,-1.671623437949821,0.23904447635377185,-0.4222726321996183,-0.3279583024282815,-0.9192951164649636,2.460676247210301,-2.409965355306981,0.6767733029431828,-0.43390180236721654,-0.8027033286049976,-0.20124736466407003,-0.13269197183141943,0.0,0.0,0.0,0.0,0.0,0.0,-1.011467425702127,1.939294365360964,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-0.9192951164649636,0.0,0.0,0.0,-0.43390180236721654,0.0,0.0,0.0,-0.2821031522542807,-1.4265797323529636,0.9175294706182825,0.3925069979997078,3.3969935603128776,2.183716803099843,-1.3094243023354486,-1.1016648922765846,-0.08376594653838038,-1.0026921372759074,2.4156484351051026,-0.3865135711507125,1.9300061045526316,-0.793039964016873,0.40297964281114806,-1.7593810296841041,-0.1888160786244468,-1.3271624206888788,-0.13311919061252606,-0.20798824978259214,-0.7736629293945084,-0.05951718173661832,0.34192221865740247,-0.045537950392261155,1.780199161839012,0.3346944256654358,-1.2081765487930605,-2.7945432486784156,0.6346021929874828,0.09072420892325629,-0.9017727217858206};

    std::vector<double> vals = {0,0,0,0,0,0,0,0.096191,0,0,0,0,0,0.562988,0.439941,0,0,0,0,0,0,0.976562,0,0,0,0,0,0,0.124878,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.124878,0,0,0,0,0,0,0,0.010812,0.006535,0.317999,0.001846,0.003814,0.009389,0.004117,0.007790,0.000647,0.000601,0.000784,0.000352,0.049294,0.000560,0.000588,0.001691,0.000419,0.000646,0.000307,0.000236,0.000341,0.000703,0.000425,0.001225,0.000808,0.617570,0.000698,0.059035,0.940965,0.033964,0.966036};


    double out1 = 0.0;
    int ret1 = dot_product1(weight1, vals, out1);
    std::cout << "out1:" << out1 << std::endl;

    double out2 = 0.0;
    int ret2 = dot_product1(weight2, vals, out2);
    std::cout << "out2:" << out2 << std::endl;

    double out3 = 0.0;
    int ret3 = dot_product1(weight3, vals, out3);
    std::cout << "out3:" << out3 << std::endl;

    double out4 = 0.0;
    int ret4 = dot_product1(weight4, vals, out4);
    std::cout << "out4:" << out4 << std::endl;

    double out5 = 0.0;
    int ret5 = dot_product1(weight5, vals, out5);
    std::cout << "out5:" << out5 << std::endl;

    std::vector<double> labels = {out1,out2,out3,out4,out5};
    std::vector<double> v_b2(labels);

    softmax(labels, v_b2);
    it = v_b2.begin();
    for (; it != v_b2.end(); ++it) {
        std::cout << *it << " ";
    }

    return 0;
}